#include "thttpd.h"
#include <sys/types.h>
#include <sys/wait.h>

//创建共享内存有关的宏
#define MAX_NODE 10 //最大支持设备，实际可用是9
#define STD_NODE_LEN sizeof(struct std_node)
#define MAX_NODE_SIZE (MAX_NODE * STD_NODE_LEN) //共享内存的大小

//共享内存中存放的节点类型
union val_t {
	int b_val;	 //bool类型存储空间
	int i_val;	 //整形值存储空间
	float f_val; //浮点值存储空间
};
struct std_node
{
	int key;			 //唯一键值
	int type;			 //数据点类型
	int dev_type;		 //数据点属于哪个设备，根据网关支持的设备自行定义
	union val_t old_val; //变化上报后需要更新旧值
	union val_t new_val; //从共享内存取出最新数据，放到new_val中
	int ret;			 //默认为-1，采集成功后设置为0，采集失败再置-1
};

static void *msg_request(void *arg)
{
	//这里客户端描述符通过参数传进来了
	int sock = (int)arg;

	// 一般情况下，线程终止后，其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。
	//但是线程也可以被置为detach状态，这样的线程一旦终止就立刻回收它占用的所有资源，而不保留终止状态。
	pthread_detach(pthread_self());

	//handler_msg作为所有的请求处理入口
	return (void *)handler_msg(sock);
}

int main(int argc, char *argv[])
{
	//****************	
	//****************
	//如果不传递端口，那么使用默认端口80
	int port = 80;

	if (argc > 1)
	{
		port = atoi(argv[1]);
	}

	//初始化服务器
	int lis_sock = init_server(port);

	while (1)
	{
		struct sockaddr_in peer;
		socklen_t len = sizeof(peer);

		int sock = accept(lis_sock, (struct sockaddr *)&peer, &len);

		if (sock < 0)
		{
			perror("accept failed");
			continue;
		}

		//每次接收一个链接后，会自动创建一个线程，这实际上就是线程服务器模型的应用
		pthread_t tid;
		if (pthread_create(&tid, NULL, msg_request, (void *)sock) > 0)
		{
			perror("pthread_create failed");
			close(sock);
		}
	}
	return 0;
}